﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using System.Threading;

namespace Taobao.Common
{
    public class TextBoxWriter:IOutputWriter
    {
        protected Mutex textBoxMutex = new Mutex(); 
        public Action<string,OutputFormatType> WriteFunc;
        public Action ClearFunc;

        #region Ctor

        public TextBoxWriter(RichTextBox textbox)
        {
            TextBox = textbox;
            WriteFunc =(message,formatType)=>{
                try
                {
                    textBoxMutex.WaitOne();
                    message = message ?? String.Empty;
                    //if (ResourceManager.Current.OptionsConfig.enablefont)
                    {
                        OutputFormat format = GetFormat(formatType);
                        TextBox.SelectionBackColor = format.BackgroundColor;
                        TextBox.SelectionColor = format.ForeColor;
                        Font oldFont = TextBox.SelectionFont;
                        if (format.Font != null)
                        {
                            TextBox.SelectionFont = format.Font;
                        }
                        TextBox.SelectionFont = oldFont;
                    }                    
                    TextBox.Select(TextBox.Text.Length, 1);
                    if (TextBox.Text.Length+message.Length > ((Int32.MaxValue/ 3) * 2))
                    {
                        TextBox.Text = message;
                    }
                    else
                    {
                        TextBox.AppendText(message);
                    }
                    TextBox.ScrollToCaret();
                    textBoxMutex.ReleaseMutex();
                }
                catch { }
            };
            ClearFunc = () => {
                textBoxMutex.WaitOne();
                TextBox.Clear();
                textBoxMutex.ReleaseMutex();
            };
        }

        #endregion

        #region Properties

        public RichTextBox TextBox
        {
            get;
            private set;
        }

        #endregion

        #region Implement IOutputWriter

        public void Write(string value)
        {
            Write(value, OutputFormatType.None);
        }

        public void Write(string message, OutputFormatType formatType)
        {
                try
                {
                    message = message ?? string.Empty;
                    //if (ResourceManager.Current.OptionsConfig.showlog)
                    {                        
                        if (TextBox.InvokeRequired)
                            TextBox.BeginInvoke(WriteFunc, message, formatType);
                        else
                        {
                            WriteFunc(message, formatType);
                        }
                    }
                }
                catch { }
            
        }

        public void WriteLine(string message)
        {
            WriteLine(message,OutputFormatType.None);
        }

        public void WriteLine(string message,OutputFormatType formatType)
        {
            try
            {
                message = message ?? string.Empty;
                if (!String.IsNullOrEmpty(message))
                {
                    message += " at " + DateTime.Now.ToString();
                }
                Write(message + Environment.NewLine, formatType);
            }
            catch { }
        }

        public void Clear()
        {
            try
            {
                //if (ResourceManager.Current.OptionsConfig.showlog)
                {
                    if (TextBox.InvokeRequired)
                        TextBox.BeginInvoke(ClearFunc);
                    else
                        ClearFunc();
                }
            }
            catch { }
            
        }

        #endregion

        #region Get OutputFormat

        public OutputFormat GetFormat(OutputFormatType formatType)
        {
            OutputFormat format =new OutputFormat ();
            switch (formatType)
            {
                case OutputFormatType.Exception:
                    {
                        format.ForeColor = Color.Red;
                        format.BackgroundColor = Color.White;
                        break;
                    }
                case OutputFormatType.Error:
                    {
                        format.ForeColor = Color.Red;
                        format.BackgroundColor = Color.White;
                        break;
                    }
                case OutputFormatType.Failed:
                    {
                        format.ForeColor = Color.Red;
                        format.BackgroundColor = Color.White;
                        break;
                    }
                case OutputFormatType.Title:
                    {
                        format.Font = new Font(TextBox.Font, FontStyle.Bold); 
                        format.ForeColor = Color.Blue;
                        format.BackgroundColor = Color.White;
                        break;
                    }
                case OutputFormatType.Success:
                    {
                        format.ForeColor = Color.Blue;
                        format.BackgroundColor = Color.White;
                        break;
                    }
                default:
                    {
                        break;
                    }
            } 
            return format;
        }

        #endregion

        #region IOutputWriter Members


        public string GetOutputText()
        {
            try
            {
                return TextBox.Text;
            }
            catch { }
            return String.Empty;
        }

        #endregion

    }

    public class OutputFormat
    {
        public Color ForeColor
        {get;set;}

        public Color BackgroundColor
        {get;set;}

        public Font Font
        { get; set; }
    }

    public enum OutputFormatType
    {
        None,

        Success,

        Failed,

        Exception,

        Error,

        Title
    }
}
